//
// GPSMapEdit
// (c) Konstantin Galichsky (kg@geopainting.com), 2006-2007
//
// RG node properties dialog - 'Numbers' page.
//

# include "StdAfx.h"
# include "Resource.h"
# include "NodeProperties.h"
# include "PropertyPages.h"
# include "Map.h"
# include "MapView.h"
# include "SetNumbers.h"
# include "ChangeCity.h"
# include "ChangeZip.h"
# include "PAHelpers.h"
# include "Settings.h"
# include "Button.h"

void CNodeNumbersPage::_FillCityLeft () {
	FillCity (m_hWnd, IDC_CITY_LEFT,  m_pCityLeft,  "<default>");
}

void CNodeNumbersPage::_FillCityRight () {
	FillCity (m_hWnd, IDC_CITY_RIGHT, m_pCityRight, "<default>");
}

void CNodeNumbersPage::_FillZipLeft () {
	FillZip  (m_hWnd, IDC_ZIP_LEFT,   m_pZipLeft,   "<default>");
}

void CNodeNumbersPage::_FillZipRight () {
	FillZip  (m_hWnd, IDC_ZIP_RIGHT,  m_pZipRight,  "<default>");
}

void CNodeNumbersPage::_EnableAll (bool _bEnable) {
	EnableDlgItem (IDC_PARITY_LEFT,  _bEnable && ! m_bLastPoint);
	EnableDlgItem (IDC_PARITY_RIGHT, _bEnable && ! m_bLastPoint);

	EnableDlgItem (IDC_LEFT_BEFORE,  _bEnable && m_bEnableLeftBefore);
	EnableDlgItem (IDC_RIGHT_BEFORE, _bEnable && m_bEnableRightBefore);

	_EnableLeftNumbers  (_bEnable);
	_EnableRightNumbers (_bEnable);
}

void CNodeNumbersPage::_EnableLeftNumbers (bool _bEnable) {
	const bool bOn = ::SendMessage (m_hLeftParity, CB_GETCURSEL, 0, 0) != 0;

	EnableDlgItem (IDC_LEFT_AFTER,        _bEnable && bOn && ! m_bLastPoint);

	EnableDlgItem (IDC_CITY_LEFT,         _bEnable && bOn && ! m_bLastPoint);
	EnableDlgItem (IDC_SELECT_CITY_LEFT,  _bEnable && bOn && ! m_bLastPoint);
	EnableDlgItem (IDC_REMOVE_CITY_LEFT,  _bEnable && bOn && ! m_bLastPoint);

	EnableDlgItem (IDC_ZIP_LEFT,          _bEnable && bOn && ! m_bLastPoint);
	EnableDlgItem (IDC_SELECT_ZIP_LEFT,   _bEnable && bOn && ! m_bLastPoint);
	EnableDlgItem (IDC_REMOVE_ZIP_LEFT,   _bEnable && bOn && ! m_bLastPoint);
}

void CNodeNumbersPage::_EnableRightNumbers (bool _bEnable) {
	const bool bOn = ::SendMessage (m_hRightParity, CB_GETCURSEL, 0, 0) != 0;

	EnableDlgItem (IDC_RIGHT_AFTER,       _bEnable && bOn && ! m_bLastPoint);

	EnableDlgItem (IDC_CITY_RIGHT,        _bEnable && bOn && ! m_bLastPoint);
	EnableDlgItem (IDC_SELECT_CITY_RIGHT, _bEnable && bOn && ! m_bLastPoint);
	EnableDlgItem (IDC_REMOVE_CITY_RIGHT, _bEnable && bOn && ! m_bLastPoint);

	EnableDlgItem (IDC_ZIP_RIGHT,         _bEnable && bOn && ! m_bLastPoint);
	EnableDlgItem (IDC_SELECT_ZIP_RIGHT,  _bEnable && bOn && ! m_bLastPoint);
	EnableDlgItem (IDC_REMOVE_ZIP_RIGHT,  _bEnable && bOn && ! m_bLastPoint);
}

bool CNodeNumbersPage::OnInit (HWND _hwndFocus) {
	CNodeProperties * const pData = static_cast<CNodeProperties *> (GetPP ());

	m_hLeftParity = GetDlgItem (IDC_PARITY_LEFT);
	::SendMessage (m_hLeftParity, CB_ADDSTRING, 0, (LPARAM) "None");
	::SendMessage (m_hLeftParity, CB_ADDSTRING, 1, (LPARAM) "Even (2, 4, 6...)");
	::SendMessage (m_hLeftParity, CB_ADDSTRING, 2, (LPARAM) "Odd (1, 3, 5...)");
	::SendMessage (m_hLeftParity, CB_ADDSTRING, 3, (LPARAM) "Both (1, 2, 3...)");
	::SendMessage (m_hLeftParity, CB_SETCURSEL, 0, 0);

	m_hRightParity = GetDlgItem (IDC_PARITY_RIGHT);
	::SendMessage (m_hRightParity, CB_ADDSTRING, 0, (LPARAM) "None");
	::SendMessage (m_hRightParity, CB_ADDSTRING, 1, (LPARAM) "Even (2, 4, 6...)");
	::SendMessage (m_hRightParity, CB_ADDSTRING, 2, (LPARAM) "Odd (1, 3, 5...)");
	::SendMessage (m_hRightParity, CB_ADDSTRING, 3, (LPARAM) "Both (1, 2, 3...)");
	::SendMessage (m_hRightParity, CB_SETCURSEL, 0, 0);

	SetButtonIcon (m_hWnd, IDC_REMOVE_CITY_LEFT,  IDI_CROSS);
	SetButtonIcon (m_hWnd, IDC_REMOVE_CITY_RIGHT, IDI_CROSS);
	SetButtonIcon (m_hWnd, IDC_REMOVE_ZIP_LEFT,   IDI_CROSS);
	SetButtonIcon (m_hWnd, IDC_REMOVE_ZIP_RIGHT,  IDI_CROSS);

	if (pData->cElement < pData->pRgn->elements.size ()) {
		const rgn_element_t & element = pData->pRgn->elements [pData->cElement];
		const size_t cPoints = element.points.size ();

		m_bLastPoint  = pData->cPoint == cPoints - 1;

		if (element.pExtra) {
			const point_extras_t & PointExtras = element.pExtra->PointExtras;
			if (pData->cPoint < PointExtras.size ()) {
				if (pData->cPoint != 0) {
					for (int nPoint = pData->cPoint - 1; nPoint >= 0; -- nPoint) {
						const numbers_t & Numbers = PointExtras [nPoint].Numbers;
						if (Numbers.bHasNumbers) {
							m_bEnableLeftBefore  = Numbers.wLeftParity  != 0;
							m_bEnableRightBefore = Numbers.wRightParity != 0;
							break;
						}
					}
				}

				const numbers_t & Numbers = PointExtras [pData->cPoint].Numbers;

				CheckDlgButton (IDC_HAS_NUMBERS, Numbers.bHasNumbers ? BST_CHECKED : BST_UNCHECKED);

				SetDlgItemUInt (IDC_LEFT_BEFORE,  Numbers.wLeftBefore);
				SetDlgItemUInt (IDC_LEFT_AFTER,   Numbers.wLeftAfter);
				SetDlgItemUInt (IDC_RIGHT_BEFORE, Numbers.wRightBefore);
				SetDlgItemUInt (IDC_RIGHT_AFTER,  Numbers.wRightAfter);

				::SendMessage (m_hLeftParity,  CB_SETCURSEL, Numbers.wLeftParity,  0);
				::SendMessage (m_hRightParity, CB_SETCURSEL, Numbers.wRightParity, 0);

				m_pCityLeft  = Numbers.pCityLeftAfter;
				m_pCityRight = Numbers.pCityRightAfter;
				m_pZipLeft   = Numbers.pZipLeftAfter;
				m_pZipRight  = Numbers.pZipRightAfter;
				_FillCityLeft  ();
				_FillCityRight ();
				_FillZipLeft   ();
				_FillZipRight  ();

				_EnableAll (Numbers.bHasNumbers);

				return true;
			}
		}
	}

	CheckDlgButton (IDC_HAS_NUMBERS, BST_UNCHECKED);
	_EnableAll (false);

	return true;
}

void CNodeNumbersPage::OnCommand (WORD _wCmd, WORD _wNotifyCode, HWND _hwndCtl) {
	switch (_wCmd) {
		case IDC_HAS_NUMBERS:
			_EnableAll (IsDlgButtonChecked (IDC_HAS_NUMBERS));
			PropSheetChanged ();
			break;

		case IDC_PARITY_LEFT:
			if (_wNotifyCode == CBN_SELCHANGE) {
				_EnableLeftNumbers (::SendMessage (m_hLeftParity,  CB_GETCURSEL, 0, 0) != 0);
				PropSheetChanged ();
			}
			break;
		case IDC_PARITY_RIGHT:
			if (_wNotifyCode == CBN_SELCHANGE) {
				_EnableRightNumbers (::SendMessage (m_hRightParity, CB_GETCURSEL, 0, 0) != 0);
				PropSheetChanged ();
			}
			break;

		case IDC_LEFT_BEFORE:
		case IDC_LEFT_AFTER:
		case IDC_RIGHT_BEFORE:
		case IDC_RIGHT_AFTER:
			if (_wNotifyCode == EN_UPDATE)
				PropSheetChanged ();
			break;

		case IDC_SELECT_CITY_LEFT:
			SelectCity (m_hWnd, true, m_pCityLeft);
			_FillCityLeft ();
			PropSheetChanged ();
			break;
		case IDC_REMOVE_CITY_LEFT:
			m_pCityLeft = NULL;
			_FillCityLeft ();
			PropSheetChanged ();
			break;

		case IDC_SELECT_CITY_RIGHT:
			SelectCity (m_hWnd, true, m_pCityRight);
			_FillCityRight ();
			PropSheetChanged ();
			break;
		case IDC_REMOVE_CITY_RIGHT:
			m_pCityRight = NULL;
			_FillCityRight ();
			PropSheetChanged ();
			break;

		case IDC_SELECT_ZIP_LEFT:
			ShowChangeZip (m_hWnd, m_pZipLeft);
			_FillZipLeft ();
			PropSheetChanged ();
			break;
		case IDC_REMOVE_ZIP_LEFT:
			m_pZipLeft = NULL;
			_FillZipLeft ();
			PropSheetChanged ();
			break;

		case IDC_SELECT_ZIP_RIGHT:
			ShowChangeZip (m_hWnd, m_pZipRight);
			_FillZipRight ();
			PropSheetChanged ();
			break;
		case IDC_REMOVE_ZIP_RIGHT:
			m_pZipRight = NULL;
			_FillZipRight ();
			PropSheetChanged ();
			break;
	}
}

void CNodeNumbersPage::OnActivatePage (const PSHNOTIFY *) {
	SaveSetting ("NodePropertiesPage", (DWORD) 2);
}

void CNodeNumbersPage::OnApply (const PSHNOTIFY *) {
	CNodeProperties * const pData = static_cast<CNodeProperties *> (GetPP ());

	if (pData->cElement < pData->pRgn->elements.size ()) {
		rgn_element_t & element = pData->pRgn->elements [pData->cElement];
		point_extras_t & PointExtras = element.pExtra->PointExtras;
		if (PointExtras.size () < element.points.size ())
			PointExtras.resize (element.points.size ());
		if (pData->cPoint < PointExtras.size ()) {
			const numbers_t & NumbersOld = PointExtras [pData->cPoint].Numbers;

			numbers_t NumbersNew = NumbersOld;
			NumbersNew.bHasNumbers  = IsDlgButtonChecked (IDC_HAS_NUMBERS);
			NumbersNew.wLeftBefore  = GetDlgItemUInt (IDC_LEFT_BEFORE);
			NumbersNew.wLeftAfter   = GetDlgItemUInt (IDC_LEFT_AFTER);
			NumbersNew.wRightBefore = GetDlgItemUInt (IDC_RIGHT_BEFORE);
			NumbersNew.wRightAfter  = GetDlgItemUInt (IDC_RIGHT_AFTER);
			NumbersNew.wLeftParity  = ::SendMessage (m_hLeftParity,  CB_GETCURSEL, 0, 0);
			NumbersNew.wRightParity = ::SendMessage (m_hRightParity, CB_GETCURSEL, 0, 0);
			NumbersNew.pCityLeftAfter  = m_pCityLeft;
			NumbersNew.pCityRightAfter = m_pCityRight;
			NumbersNew.pZipLeftAfter   = m_pZipLeft;
			NumbersNew.pZipRightAfter  = m_pZipRight;

			if (! (NumbersNew == NumbersOld)) {
				SetNumbers (pData->pRgn, pData->cElement, pData->cPoint, NumbersNew);

				if (g_bShowNumbers)
					Refresh ();
			}
		}
	}
}
